make xmlgeneric a class (#1244)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Thu, 30 Nov 2023 12:40:13 +0000 (05:40 -0700)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2023 12:40:13 +0000 (05:40 -0700)
* make xmlgeneric a class.

* encapsulate more of xmlgeneric

* use scoped enum

* encapsulate a bit more.

* retire xg_string type

* use scoped enums

* rule of zero applied to xmlgeneric class.

* remove test code

gtrnctr.cc
gtrnctr.h
kml.cc
kml.h
osm.cc
osm.h
xmlgeneric.cc
xmlgeneric.h

index f53cccef66259246678c7ec3cddd60b7ffbade66..5a306a79f61f9c823dc8024a61195f7934774998 100644 (file)
@@ -38,7 +38,7 @@
 #include <type_traits>           // for add_const<>::type
 
 #include "defs.h"                // for Waypoint, route_head, computed_trkdata, waypt_add, route_disp, track_disp_all, case_ignore_strncmp, track_add_head, track_add_wpt, track_recompute, xml_parse_time, CSTR, wp_flags, WAYPT_SET, unknown_alt
-#include "xmlgeneric.h"          // for xg_string, build_xg_tag_map, xml_deinit, xml_init, xml_read
+#include "xmlgeneric.h"          // for xml_deinit, xml_init, xml_read
 
 
 #define MYNAME "gtc"
 void
 GtrnctrFormat::rd_init(const QString& fname)
 {
-  xml_init(fname, build_xg_tag_map(this, gtc_map), nullptr, gtc_tags_to_ignore, nullptr, true);
+  xml_reader = new XmlGenericReader;
+  xml_reader->xml_init(fname, this, gtc_map, nullptr, gtc_tags_to_ignore, nullptr);
 }
 
 void
 GtrnctrFormat::read()
 {
-  xml_read();
+  xml_reader->xml_read();
 }
 
 void
 GtrnctrFormat::rd_deinit()
 {
-  xml_deinit();
+  delete xml_reader;
+  xml_reader = nullptr;
 }
 
 void
@@ -359,39 +361,39 @@ GtrnctrFormat::write()
 }
 
 void
-GtrnctrFormat::gtc_trk_s(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_s(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   trk_head = new route_head;
   track_add_head(trk_head);
 }
 
 void
-GtrnctrFormat::gtc_trk_ident(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_ident(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   trk_head->rte_name = args;
 }
 
 void
-GtrnctrFormat::gtc_trk_lap_s(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_lap_s(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   lap_ct++;
   lap_s = 1;
 }
 
 void
-GtrnctrFormat::gtc_trk_lap_e(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_lap_e(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   lap_s = 0;
 }
 
 void
-GtrnctrFormat::gtc_trk_pnt_s(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_pnt_s(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp = new Waypoint;
 }
 
 void
-GtrnctrFormat::gtc_trk_pnt_e(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_pnt_e(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) {
     if (lap_s) {
@@ -414,25 +416,25 @@ GtrnctrFormat::gtc_trk_pnt_e(xg_string /*unused*/, const QXmlStreamAttributes* /
 }
 
 void
-GtrnctrFormat::gtc_trk_utc(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_utc(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->creation_time = xml_parse_time(args);
 }
 
 void
-GtrnctrFormat::gtc_trk_lat(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_lat(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->latitude = args.toDouble();
 }
 
 void
-GtrnctrFormat::gtc_trk_long(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_long(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->longitude = args.toDouble();
 }
 
 void
-GtrnctrFormat::gtc_trk_alt(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_alt(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->altitude = args.toDouble();
 }
@@ -451,13 +453,13 @@ void GtrnctrFormat::gtc_trk_cad(const QString& args, const QXmlStreamAttributes*
 }
 
 void
-GtrnctrFormat::gtc_trk_pwr(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_pwr(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->power = args.toDouble();
 }
 
 void
-GtrnctrFormat::gtc_trk_spd(xg_string args, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_trk_spd(const QString& args, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp->set_speed(args.toDouble());
 }
@@ -469,7 +471,7 @@ GtrnctrFormat::gtc_wpt_crs_s(const QString& /*unused*/, const QXmlStreamAttribut
 }
 
 void
-GtrnctrFormat::gtc_wpt_crs_e(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_wpt_crs_e(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) {
     waypt_add(wpt_tmp);
@@ -481,14 +483,14 @@ GtrnctrFormat::gtc_wpt_crs_e(xg_string /*unused*/, const QXmlStreamAttributes* /
 }
 
 void
-GtrnctrFormat::gtc_wpt_pnt_s(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_wpt_pnt_s(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   wpt_tmp = new Waypoint;
   lap_ct++;
 }
 
 void
-GtrnctrFormat::gtc_wpt_pnt_e(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+GtrnctrFormat::gtc_wpt_pnt_e(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) {
     /* Add the begin position of a CourseLap as
index 28a11d1080d81055609d04fdc48b5d9286445b35..654b0d9951238668d09735d22bd4a15b78181657 100644 (file)
--- a/gtrnctr.h
+++ b/gtrnctr.h
@@ -35,7 +35,7 @@
 #include "format.h"              // for Format
 #include "gbfile.h"              // for gbfile
 #include "src/core/datetime.h"   // for DateTime
-#include "xmlgeneric.h"          // for cb_cdata, xg_functor_map_entry, xg_string, cb_start, cb_end
+#include "xmlgeneric.h"          // for cb_cdata, xg_functor_map_entry, cb_start, cb_end
 
 
 class GtrnctrFormat : public Format
@@ -97,25 +97,25 @@ private:
   void gtc_crs_hdr(const route_head* rte);
   void gtc_crs_ftr(const route_head*  /* unused */);
 
-  void gtc_trk_s(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_ident(xg_string args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_lap_s(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_lap_e(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_pnt_s(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_pnt_e(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_utc(xg_string args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_lat(xg_string args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_long(xg_string args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_alt(xg_string args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_s(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_ident(const QString& args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_lap_s(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_lap_e(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_pnt_s(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_pnt_e(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_utc(const QString& args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_lat(const QString& args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_long(const QString& args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_alt(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_trk_dist(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_trk_hr(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_trk_cad(const QString& args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_pwr(xg_string args, const QXmlStreamAttributes*  /* unused */);
-  void gtc_trk_spd(xg_string args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_pwr(const QString& args, const QXmlStreamAttributes*  /* unused */);
+  void gtc_trk_spd(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_wpt_crs_s(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_wpt_crs_e(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_wpt_pnt_s(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
-  void gtc_wpt_pnt_e(xg_string  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_wpt_crs_e(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_wpt_pnt_s(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
+  void gtc_wpt_pnt_e(const QString&  /* unused */, const QXmlStreamAttributes*  /* unused */);
   void gtc_wpt_ident(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_wpt_lat(const QString& args, const QXmlStreamAttributes*  /* unused */);
   void gtc_wpt_long(const QString& args, const QXmlStreamAttributes*  /* unused */);
@@ -154,71 +154,72 @@ private:
     },
   };
 
-  QList<xg_functor_map_entry<GtrnctrFormat>> gtc_map = {
+  QList<XmlGenericReader::xg_fmt_map_entry<GtrnctrFormat>> gtc_map = {
     /* courses tcx v1 & v2 */
-    { &GtrnctrFormat::gtc_trk_s,    cb_start, "/Courses/Course" },
-    { &GtrnctrFormat::gtc_trk_ident,cb_cdata, "/Courses/Course/Name"},
-    { &GtrnctrFormat::gtc_trk_pnt_s,cb_start, "/Courses/Course/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_pnt_e,cb_end,   "/Courses/Course/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_utc,  cb_cdata, "/Courses/Course/Track/Trackpoint/Time" },
-    { &GtrnctrFormat::gtc_trk_lat,  cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_long, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_alt,  cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" },
-    { &GtrnctrFormat::gtc_trk_hr,   cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" },
-    { &GtrnctrFormat::gtc_trk_cad,  cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" },
-    { &GtrnctrFormat::gtc_wpt_crs_s,cb_start, "/Courses/Course/CoursePoint" },
-    { &GtrnctrFormat::gtc_wpt_crs_e,cb_end,   "/Courses/Course/CoursePoint" },
-    { &GtrnctrFormat::gtc_wpt_ident,cb_cdata, "/Courses/Course/CoursePoint/Name"},
-    { &GtrnctrFormat::gtc_trk_utc,  cb_cdata, "/Courses/Course/CoursePoint/Time"},
-    { &GtrnctrFormat::gtc_wpt_lat,  cb_cdata, "/Courses/Course/CoursePoint/Position/LatitudeDegrees"},
-    { &GtrnctrFormat::gtc_wpt_long, cb_cdata, "/Courses/Course/CoursePoint/Position/LongitudeDegrees"},
-    { &GtrnctrFormat::gtc_trk_alt,  cb_cdata, "/Courses/Course/CoursePoint/AltitudeMeters" },
-    { &GtrnctrFormat::gtc_wpt_icon, cb_cdata, "/Courses/Course/CoursePoint/PointType" },
-    { &GtrnctrFormat::gtc_wpt_notes,cb_cdata, "/Courses/Course/CoursePoint/Notes" },
+    { &GtrnctrFormat::gtc_trk_s, xg_cb_type::cb_start, "/Courses/Course" },
+    { &GtrnctrFormat::gtc_trk_ident, xg_cb_type::cb_cdata, "/Courses/Course/Name"},
+    { &GtrnctrFormat::gtc_trk_pnt_s, xg_cb_type::cb_start, "/Courses/Course/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_pnt_e, xg_cb_type::cb_end,   "/Courses/Course/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_utc, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/Time" },
+    { &GtrnctrFormat::gtc_trk_lat, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_long, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_alt, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" },
+    { &GtrnctrFormat::gtc_trk_hr, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" },
+    { &GtrnctrFormat::gtc_trk_cad, xg_cb_type::cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" },
+    { &GtrnctrFormat::gtc_wpt_crs_s, xg_cb_type::cb_start, "/Courses/Course/CoursePoint" },
+    { &GtrnctrFormat::gtc_wpt_crs_e, xg_cb_type::cb_end,   "/Courses/Course/CoursePoint" },
+    { &GtrnctrFormat::gtc_wpt_ident, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/Name"},
+    { &GtrnctrFormat::gtc_trk_utc, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/Time"},
+    { &GtrnctrFormat::gtc_wpt_lat, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/Position/LatitudeDegrees"},
+    { &GtrnctrFormat::gtc_wpt_long, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/Position/LongitudeDegrees"},
+    { &GtrnctrFormat::gtc_trk_alt, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/AltitudeMeters" },
+    { &GtrnctrFormat::gtc_wpt_icon, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/PointType" },
+    { &GtrnctrFormat::gtc_wpt_notes, xg_cb_type::cb_cdata, "/Courses/Course/CoursePoint/Notes" },
 
     /* history tcx v2 (activities) */
-    { &GtrnctrFormat::gtc_trk_s,    cb_start, "/Activities/Activity" },
-    { &GtrnctrFormat::gtc_trk_ident,cb_cdata, "/Activities/Activity/Id" },
-    { &GtrnctrFormat::gtc_trk_lap_s,cb_start, "/Activities/Activity/Lap" },
-    { &GtrnctrFormat::gtc_trk_lap_e,cb_end,   "/Activities/Activity/Lap" },
-    { &GtrnctrFormat::gtc_trk_pnt_s,cb_start, "/Activities/Activity/Lap/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_pnt_e,cb_end,   "/Activities/Activity/Lap/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_utc,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" },
-    { &GtrnctrFormat::gtc_trk_lat,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_long, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_alt,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" },
-    { &GtrnctrFormat::gtc_trk_dist, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/DistanceMeters" },
-    { &GtrnctrFormat::gtc_trk_hr,   cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" },
-    { &GtrnctrFormat::gtc_trk_cad,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" },
-    { &GtrnctrFormat::gtc_trk_pwr,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" },
+    { &GtrnctrFormat::gtc_trk_s, xg_cb_type::cb_start, "/Activities/Activity" },
+    { &GtrnctrFormat::gtc_trk_ident, xg_cb_type::cb_cdata, "/Activities/Activity/Id" },
+    { &GtrnctrFormat::gtc_trk_lap_s, xg_cb_type::cb_start, "/Activities/Activity/Lap" },
+    { &GtrnctrFormat::gtc_trk_lap_e, xg_cb_type::cb_end,   "/Activities/Activity/Lap" },
+    { &GtrnctrFormat::gtc_trk_pnt_s, xg_cb_type::cb_start, "/Activities/Activity/Lap/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_pnt_e, xg_cb_type::cb_end,   "/Activities/Activity/Lap/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_utc, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" },
+    { &GtrnctrFormat::gtc_trk_lat, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_long, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_alt, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" },
+    { &GtrnctrFormat::gtc_trk_dist, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/DistanceMeters" },
+    { &GtrnctrFormat::gtc_trk_hr, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" },
+    { &GtrnctrFormat::gtc_trk_cad, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" },
+    { &GtrnctrFormat::gtc_trk_pwr, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" },
     // Sample from Marcelo Kittlein 5/2014 declares a default namespace with the start tag of the TPX element,
     // and thus doesn't use prefixes.
-    { &GtrnctrFormat::gtc_trk_pwr,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/TPX/Watts" },
+    { &GtrnctrFormat::gtc_trk_pwr, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/TPX/Watts" },
     // It looks like Speed and Watts should be siblings, but Garmin can't get
     // their namespace act very consistent.  This works for a sample provided
     // by Laurent Desmons in 5/2013.
-    { &GtrnctrFormat::gtc_trk_spd,  cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/TPX/Speed" },
+    { &GtrnctrFormat::gtc_trk_spd, xg_cb_type::cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/TPX/Speed" },
 
     /* history tcx v1 */
-    { &GtrnctrFormat::gtc_trk_s,    cb_start, "/History/Run" },
-    { &GtrnctrFormat::gtc_trk_ident,cb_cdata, "/History/Run/Id" },
-    { &GtrnctrFormat::gtc_trk_lap_s,cb_start, "/History/Run/Lap" },
-    { &GtrnctrFormat::gtc_trk_lap_e,cb_end,   "/History/Run/Lap" },
-    { &GtrnctrFormat::gtc_trk_pnt_s,cb_start, "/History/Run/Lap/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_pnt_e,cb_end,   "/History/Run/Lap/Track/Trackpoint" },
-    { &GtrnctrFormat::gtc_trk_utc,  cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" },
-    { &GtrnctrFormat::gtc_trk_lat,  cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_long, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_alt,  cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" },
-    { &GtrnctrFormat::gtc_trk_hr,   cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" },
-    { &GtrnctrFormat::gtc_trk_cad,  cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" },
-
-    { &GtrnctrFormat::gtc_wpt_pnt_s,cb_start, "/Courses/Course/Lap/BeginPosition" },
-    { &GtrnctrFormat::gtc_wpt_pnt_e,cb_end, "/Courses/Course/Lap/BeginPosition" },
-    { &GtrnctrFormat::gtc_wpt_lat,  cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" },
-    { &GtrnctrFormat::gtc_wpt_long, cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" },
-    { &GtrnctrFormat::gtc_trk_alt,  cb_cdata, "/Courses/Course/Lap/BeginAltitudeMeters" }
+    { &GtrnctrFormat::gtc_trk_s, xg_cb_type::cb_start, "/History/Run" },
+    { &GtrnctrFormat::gtc_trk_ident, xg_cb_type::cb_cdata, "/History/Run/Id" },
+    { &GtrnctrFormat::gtc_trk_lap_s, xg_cb_type::cb_start, "/History/Run/Lap" },
+    { &GtrnctrFormat::gtc_trk_lap_e, xg_cb_type::cb_end,   "/History/Run/Lap" },
+    { &GtrnctrFormat::gtc_trk_pnt_s, xg_cb_type::cb_start, "/History/Run/Lap/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_pnt_e, xg_cb_type::cb_end,   "/History/Run/Lap/Track/Trackpoint" },
+    { &GtrnctrFormat::gtc_trk_utc, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" },
+    { &GtrnctrFormat::gtc_trk_lat, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_long, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_alt, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" },
+    { &GtrnctrFormat::gtc_trk_hr, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" },
+    { &GtrnctrFormat::gtc_trk_cad, xg_cb_type::cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" },
+
+    { &GtrnctrFormat::gtc_wpt_pnt_s, xg_cb_type::cb_start, "/Courses/Course/Lap/BeginPosition" },
+    { &GtrnctrFormat::gtc_wpt_pnt_e, xg_cb_type::cb_end, "/Courses/Course/Lap/BeginPosition" },
+    { &GtrnctrFormat::gtc_wpt_lat, xg_cb_type::cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" },
+    { &GtrnctrFormat::gtc_wpt_long, xg_cb_type::cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" },
+    { &GtrnctrFormat::gtc_trk_alt, xg_cb_type::cb_cdata, "/Courses/Course/Lap/BeginAltitudeMeters" }
   };
+  XmlGenericReader* xml_reader{nullptr};
 
   int gtc_indent_level{};
 };
diff --git a/kml.cc b/kml.cc
index 8e59b3eca954e33056fba438f03d0af0cfe2585b..d7e9c826b49a9cba1d200b4a472f6efaf9173fe2 100644 (file)
--- a/kml.cc
+++ b/kml.cc
@@ -57,7 +57,7 @@
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
 #include "src/core/xmltag.h"           // for xml_findfirst, xml_tag, fs_xml, xml_attribute, xml_findnext
 #include "units.h"                     // for UnitsFormatter, UnitsFormatter...
-#include "xmlgeneric.h"                // for cb_cdata, cb_end, cb_start, xg_callback, xg_string, xg_cb_type, xml_deinit, xml_ignore_tags, xml_init, xml_read, xg_tag_mapping
+#include "xmlgeneric.h"                // for cb_cdata, cb_end, cb_start, xg_callback, xg_cb_type, xml_deinit, xml_ignore_tags, xml_init, xml_read, xg_tag_mapping
 
 
 //  Icons provided and hosted by Google.  Used with permission.
@@ -134,7 +134,7 @@ void KmlFormat::kml_step_color()
   kml_color_sequencer.seq += kml_color_sequencer.step;
 }
 
-void KmlFormat::wpt_s(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_s(const QString& /*args*/, const QXmlStreamAttributes* /*attrs*/)
 {
   if (wpt_tmp) {
     fatal(MYNAME ": wpt_s: invalid kml file\n");
@@ -148,7 +148,7 @@ void KmlFormat::wpt_s(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
   wpt_timespan_end = gpsbabel::DateTime();
 }
 
-void KmlFormat::wpt_e(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_e(const QString& /*args*/, const QXmlStreamAttributes* /*attrs*/)
 {
   if (!wpt_tmp) {
     fatal(MYNAME ": wpt_e: invalid kml file\n");
@@ -163,7 +163,7 @@ void KmlFormat::wpt_e(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
   wpt_tmp_queued = false;
 }
 
-void KmlFormat::wpt_name(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_name(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   if (!wpt_tmp) {
     fatal(MYNAME ": wpt_name: invalid kml file\n");
@@ -179,7 +179,7 @@ void KmlFormat::wpt_desc(const QString& args, const QXmlStreamAttributes* /*attr
   wpt_tmp->description += args.trimmed();
 }
 
-void KmlFormat::wpt_time(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_time(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   if (!wpt_tmp) {
     fatal(MYNAME ": wpt_time: invalid kml file\n");
@@ -187,12 +187,12 @@ void KmlFormat::wpt_time(xg_string args, const QXmlStreamAttributes* /*attrs*/)
   wpt_tmp->SetCreationTime(xml_parse_time(args));
 }
 
-void KmlFormat::wpt_ts_begin(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_ts_begin(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   wpt_timespan_begin = xml_parse_time(args);
 }
 
-void KmlFormat::wpt_ts_end(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_ts_end(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   wpt_timespan_end = xml_parse_time(args);
 }
@@ -215,14 +215,14 @@ void KmlFormat::wpt_coord(const QString& args, const QXmlStreamAttributes* /*att
   wpt_tmp_queued = true;
 }
 
-void KmlFormat::wpt_icon(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::wpt_icon(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   if (wpt_tmp)  {
     wpt_tmp->icon_descr = args;
   }
 }
 
-void KmlFormat::trk_coord(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::trk_coord(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   auto* trk_head = new route_head;
   if (wpt_tmp && !wpt_tmp->shortname.isEmpty()) {
@@ -274,7 +274,7 @@ void KmlFormat::trk_coord(xg_string args, const QXmlStreamAttributes* /*attrs*/)
   }
 }
 
-void KmlFormat::gx_trk_s(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::gx_trk_s(const QString& /*args*/, const QXmlStreamAttributes* /*attrs*/)
 {
   gx_trk_head = new route_head;
   if (wpt_tmp && !wpt_tmp->shortname.isEmpty()) {
@@ -290,7 +290,7 @@ void KmlFormat::gx_trk_s(xg_string /*args*/, const QXmlStreamAttributes* /*attrs
   gx_trk_coords = new QList<std::tuple<int, double, double, double>>;
 }
 
-void KmlFormat::gx_trk_e(xg_string /*args*/, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::gx_trk_e(const QString& /*args*/, const QXmlStreamAttributes* /*attrs*/)
 {
   // Check that for every temporal value (kml:when) in a kml:Track there is a position (kml:coord) value.
   // Check that for every temporal value (kml:when) in a gx:Track there is a position (gx:coord) value.
@@ -331,7 +331,7 @@ void KmlFormat::gx_trk_e(xg_string /*args*/, const QXmlStreamAttributes* /*attrs
   gx_trk_coords = nullptr;
 }
 
-void KmlFormat::gx_trk_when(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::gx_trk_when(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   if (! gx_trk_times) {
     fatal(MYNAME ": gx_trk_when: invalid kml file\n");
@@ -339,7 +339,7 @@ void KmlFormat::gx_trk_when(xg_string args, const QXmlStreamAttributes* /*attrs*
   gx_trk_times->append(xml_parse_time(args));
 }
 
-void KmlFormat::gx_trk_coord(xg_string args, const QXmlStreamAttributes* /*attrs*/)
+void KmlFormat::gx_trk_coord(const QString& args, const QXmlStreamAttributes* /*attrs*/)
 {
   if (! gx_trk_coords) {
     fatal(MYNAME ": gx_trk_coord: invalid kml file\n");
@@ -355,17 +355,19 @@ void KmlFormat::gx_trk_coord(xg_string args, const QXmlStreamAttributes* /*attrs
 
 void KmlFormat::rd_init(const QString& fname)
 {
-  xml_init(fname, build_xg_tag_map(this, kml_map), nullptr, kml_tags_to_ignore, kml_tags_to_skip, true);
+  xml_reader = new XmlGenericReader;
+  xml_reader->xml_init(fname, this, kml_map, nullptr, kml_tags_to_ignore, kml_tags_to_skip);
 }
 
 void KmlFormat::read()
 {
-  xml_read();
+  xml_reader->xml_read();
 }
 
 void KmlFormat::rd_deinit()
 {
-  xml_deinit();
+  delete xml_reader;
+  xml_reader = nullptr;
 }
 
 void KmlFormat::wr_init(const QString& fname)
diff --git a/kml.h b/kml.h
index 64b7f1f721fda2a5225ccf1a3ba56adcf892174e..eef489c57b4d1066ca4970f3af0da0522c189062 100644 (file)
--- a/kml.h
+++ b/kml.h
@@ -37,7 +37,7 @@
 #include "src/core/file.h"              // for File
 #include "src/core/xmlstreamwriter.h"   // for XmlStreamWriter
 #include "units.h"                      // for UnitsFormatter
-#include "xmlgeneric.h"                 // for cb_cdata, cb_end, cb_start, xg_callback, xg_string, xg_cb_type, xml_deinit, xml_ignore_tags, xml_init, xml_read, xg_tag_mapping
+#include "xmlgeneric.h"                 // for cb_cdata, cb_end, cb_start, xg_callback, xg_cb_type, xml_deinit, xml_ignore_tags, xml_init, xml_read, xg_tag_mapping
 
 
 class KmlFormat : public Format
@@ -331,29 +331,30 @@ private:
     gb_color color;
   } kml_color_sequencer;
 
-  QList<xg_functor_map_entry<KmlFormat>> kml_map = {
-    {&KmlFormat::wpt_s, cb_start, "/Placemark"},
-    {&KmlFormat::wpt_e, cb_end, "/Placemark"},
-    {&KmlFormat::wpt_name, cb_cdata, "/Placemark/name"},
-    {&KmlFormat::wpt_desc, cb_cdata, "/Placemark/description"},
-    {&KmlFormat::wpt_ts_begin, cb_cdata,"/Placemark/TimeSpan/begin"},
-    {&KmlFormat::wpt_ts_end, cb_cdata, "/Placemark/TimeSpan/end"},
-    {&KmlFormat::wpt_time, cb_cdata, "/Placemark/TimeStamp/when"},
+  QList<XmlGenericReader::xg_fmt_map_entry<KmlFormat>> kml_map = {
+    {&KmlFormat::wpt_s, xg_cb_type::cb_start, "/Placemark"},
+    {&KmlFormat::wpt_e, xg_cb_type::cb_end, "/Placemark"},
+    {&KmlFormat::wpt_name, xg_cb_type::cb_cdata, "/Placemark/name"},
+    {&KmlFormat::wpt_desc, xg_cb_type::cb_cdata, "/Placemark/description"},
+    {&KmlFormat::wpt_ts_begin, xg_cb_type::cb_cdata,"/Placemark/TimeSpan/begin"},
+    {&KmlFormat::wpt_ts_end, xg_cb_type::cb_cdata, "/Placemark/TimeSpan/end"},
+    {&KmlFormat::wpt_time, xg_cb_type::cb_cdata, "/Placemark/TimeStamp/when"},
     // Alias for above used in KML 2.0
-    {&KmlFormat::wpt_time, cb_cdata, "/Placemark/TimeInstant/timePosition"},
-    {&KmlFormat::wpt_coord, cb_cdata, "/Placemark/(.+/)?Point/coordinates"},
-    {&KmlFormat::wpt_icon, cb_cdata, "/Placemark/Style/Icon/href"},
-    {&KmlFormat::trk_coord, cb_cdata, "/Placemark/(.+/)?LineString/coordinates"},
-    {&KmlFormat::trk_coord, cb_cdata, "/Placemark/(.+)/?LinearRing/coordinates"},
-    {&KmlFormat::gx_trk_s,  cb_start, "/Placemark/(.+/)?gx:Track"},
-    {&KmlFormat::gx_trk_e,  cb_end, "/Placemark/(.+/)?gx:Track"},
-    {&KmlFormat::gx_trk_when,  cb_cdata, "/Placemark/(.+/)?gx:Track/when"},
-    {&KmlFormat::gx_trk_coord, cb_cdata, "/Placemark/(.+/)?gx:Track/gx:coord"},
-    {&KmlFormat::gx_trk_s,  cb_start, "/Placemark/(.+/)?Track"}, // KML 2.3
-    {&KmlFormat::gx_trk_e,  cb_end, "/Placemark/(.+/)?Track"}, // KML 2.3
-    {&KmlFormat::gx_trk_when,  cb_cdata, "/Placemark/(.+/)?Track/when"}, // KML 2.3
-    {&KmlFormat::gx_trk_coord, cb_cdata, "/Placemark/(.+/)?Track/coord"}, // KML 2.3
+    {&KmlFormat::wpt_time, xg_cb_type::cb_cdata, "/Placemark/TimeInstant/timePosition"},
+    {&KmlFormat::wpt_coord, xg_cb_type::cb_cdata, "/Placemark/(.+/)?Point/coordinates"},
+    {&KmlFormat::wpt_icon, xg_cb_type::cb_cdata, "/Placemark/Style/Icon/href"},
+    {&KmlFormat::trk_coord, xg_cb_type::cb_cdata, "/Placemark/(.+/)?LineString/coordinates"},
+    {&KmlFormat::trk_coord, xg_cb_type::cb_cdata, "/Placemark/(.+)/?LinearRing/coordinates"},
+    {&KmlFormat::gx_trk_s, xg_cb_type::cb_start, "/Placemark/(.+/)?gx:Track"},
+    {&KmlFormat::gx_trk_e, xg_cb_type::cb_end, "/Placemark/(.+/)?gx:Track"},
+    {&KmlFormat::gx_trk_when, xg_cb_type::cb_cdata, "/Placemark/(.+/)?gx:Track/when"},
+    {&KmlFormat::gx_trk_coord, xg_cb_type::cb_cdata, "/Placemark/(.+/)?gx:Track/gx:coord"},
+    {&KmlFormat::gx_trk_s, xg_cb_type::cb_start, "/Placemark/(.+/)?Track"}, // KML 2.3
+    {&KmlFormat::gx_trk_e, xg_cb_type::cb_end, "/Placemark/(.+/)?Track"}, // KML 2.3
+    {&KmlFormat::gx_trk_when, xg_cb_type::cb_cdata, "/Placemark/(.+/)?Track/when"}, // KML 2.3
+    {&KmlFormat::gx_trk_coord, xg_cb_type::cb_cdata, "/Placemark/(.+/)?Track/coord"}, // KML 2.3
   };
+  XmlGenericReader* xml_reader{nullptr};
 
   // The TimeSpan/begin and TimeSpan/end DateTimes:
   gpsbabel::DateTime wpt_timespan_begin, wpt_timespan_end;
diff --git a/osm.cc b/osm.cc
index 1409cc831ea9827c151a8f442ea0407854d92611..298f0b07c67fef4822fcc8c394e1dd44668d7041 100644 (file)
--- a/osm.cc
+++ b/osm.cc
@@ -34,7 +34,7 @@
 #include "osm.h"
 #include "src/core/datetime.h"         // for DateTime
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
-#include "xmlgeneric.h"                // for xg_string, build_xg_tag_map, xml_deinit, xml_init, xml_read
+#include "xmlgeneric.h"                // for xml_deinit, xml_init, xml_read
 
 
 #define MYNAME "osm"
@@ -413,7 +413,7 @@ OsmFormat::osm_strip_html(const QString& str)
 }
 
 void
-OsmFormat::osm_node_end(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+OsmFormat::osm_node_end(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (wpt) {
     if (wpt->wpt_flags.fmt_use) {
@@ -426,7 +426,7 @@ OsmFormat::osm_node_end(xg_string /*unused*/, const QXmlStreamAttributes* /*unus
 }
 
 void
-OsmFormat::osm_node(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_node(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   wpt = new Waypoint;
 
@@ -457,7 +457,7 @@ OsmFormat::osm_node(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 }
 
 void
-OsmFormat::osm_node_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_node_tag(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   QString key, value;
   signed char ikey;
@@ -510,7 +510,7 @@ OsmFormat::osm_node_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 }
 
 void
-OsmFormat::osm_way(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_way(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   rte = new route_head;
   // create a wpt to represent the route center if it has a center tag
@@ -521,7 +521,7 @@ OsmFormat::osm_way(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 }
 
 void
-OsmFormat::osm_way_nd(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_way_nd(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   if (attrv->hasAttribute("ref")) {
     QString atstr = attrv->value("ref").toString();
@@ -537,7 +537,7 @@ OsmFormat::osm_way_nd(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 }
 
 void
-OsmFormat::osm_way_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_way_tag(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   QString key, value;
   signed char ikey;
@@ -574,7 +574,7 @@ OsmFormat::osm_way_tag(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
 }
 
 void
-OsmFormat::osm_way_center(xg_string /*unused*/, const QXmlStreamAttributes* attrv)
+OsmFormat::osm_way_center(const QString& /*unused*/, const QXmlStreamAttributes* attrv)
 {
   wpt->wpt_flags.fmt_use = 1;
 
@@ -587,7 +587,7 @@ OsmFormat::osm_way_center(xg_string /*unused*/, const QXmlStreamAttributes* attr
 }
 
 void
-OsmFormat::osm_way_end(xg_string /*unused*/, const QXmlStreamAttributes* /*unused*/)
+OsmFormat::osm_way_end(const QString& /*unused*/, const QXmlStreamAttributes* /*unused*/)
 {
   if (rte) {
     route_add_head(rte);
@@ -615,19 +615,22 @@ OsmFormat::rd_init(const QString& fname)
     osm_features_init();
   }
 
-  xml_init(fname, build_xg_tag_map(this, osm_map), nullptr, nullptr, nullptr, true);
+  xml_reader = new XmlGenericReader;
+  xml_reader->xml_init(fname, this, osm_map);
 }
 
 void
 OsmFormat::read()
 {
-  xml_read();
+  xml_reader->xml_read();
 }
 
 void
 OsmFormat::rd_deinit()
 {
-  xml_deinit();
+  delete xml_reader;
+  xml_reader = nullptr;
+
   waypoints.clear();
 }
 
diff --git a/osm.h b/osm.h
index 87590b45bd9bfef8194fed9c245552be593a87fe..4a07c235068d9dd82f763559a83afabdab3a8555 100644 (file)
--- a/osm.h
+++ b/osm.h
@@ -33,7 +33,7 @@
 #include "format.h"                    // for Format
 #include "src/core/file.h"             // for File
 #include "src/core/xmlstreamwriter.h"  // for XmlStreamWriter
-#include "xmlgeneric.h"                // for xg_functor_map_entry, cb_start, cb_end, xg_string
+#include "xmlgeneric.h"                // for xg_functor_map_entry, cb_start, cb_end
 
 
 class OsmFormat : public Format
@@ -88,14 +88,14 @@ private:
   char osm_feature_ikey(const QString& key) const;
   QString osm_feature_symbol(int ikey, const char* value) const;
   static QString osm_strip_html(const QString& str);
-  void osm_node_end(xg_string /* unused */, const QXmlStreamAttributes* /* unused */);
-  void osm_node(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_node_tag(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_way(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_way_nd(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_way_tag(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_way_center(xg_string /* unused */, const QXmlStreamAttributes* attrv);
-  void osm_way_end(xg_string /* unused */, const QXmlStreamAttributes* /* unused */);
+  void osm_node_end(const QString& /* unused */, const QXmlStreamAttributes* /* unused */);
+  void osm_node(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_node_tag(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_nd(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_tag(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_center(const QString& /* unused */, const QXmlStreamAttributes* attrv);
+  void osm_way_end(const QString& /* unused */, const QXmlStreamAttributes* /* unused */);
   void osm_init_icons();
   void osm_write_tag(const QString& key, const QString& value) const;
   void osm_disp_feature(const Waypoint* waypoint) const;
@@ -133,15 +133,16 @@ private:
   route_head* rte{};
   Waypoint* wpt{};
 
-  QList<xg_functor_map_entry<OsmFormat>> osm_map = {
-    {&OsmFormat::osm_node,     cb_start,       "/osm/node"},
-    {&OsmFormat::osm_node_tag, cb_start,       "/osm/node/tag"},
-    {&OsmFormat::osm_node_end, cb_end,         "/osm/node"},
-    {&OsmFormat::osm_way,      cb_start,       "/osm/way"},
-    {&OsmFormat::osm_way_nd,   cb_start,       "/osm/way/nd"},
-    {&OsmFormat::osm_way_tag,  cb_start,       "/osm/way/tag"},
-    {&OsmFormat::osm_way_center,       cb_start,       "/osm/way/center"},
-    {&OsmFormat::osm_way_end,  cb_end,         "/osm/way"}
+  QList<XmlGenericReader::xg_fmt_map_entry<OsmFormat>> osm_map  {
+    {&OsmFormat::osm_node, xg_cb_type::cb_start,       "/osm/node"},
+    {&OsmFormat::osm_node_tag, xg_cb_type::cb_start,   "/osm/node/tag"},
+    {&OsmFormat::osm_node_end, xg_cb_type::cb_end,             "/osm/node"},
+    {&OsmFormat::osm_way, xg_cb_type::cb_start,        "/osm/way"},
+    {&OsmFormat::osm_way_nd, xg_cb_type::cb_start,     "/osm/way/nd"},
+    {&OsmFormat::osm_way_tag, xg_cb_type::cb_start,    "/osm/way/tag"},
+    {&OsmFormat::osm_way_center, xg_cb_type::cb_start, "/osm/way/center"},
+    {&OsmFormat::osm_way_end, xg_cb_type::cb_end,              "/osm/way"}
   };
+  XmlGenericReader* xml_reader{nullptr};
 };
 #endif // OSM_H_INCLUDED_
index 0d5a70c24cadf8d6b2beda9dc3b334e63fb0b351..1aae5b6e7ac0cd44822857392feac012fbb072d3 100644 (file)
 
  */
 
-#include <QByteArray>                   // for QByteArray
-#include <QHash>                        // for QHash
-#include <QIODevice>                    // for QIODevice, QIODevice::ReadOnly
-#include <QLatin1Char>                  // for QLatin1Char
-#include <QList>
-#include <QStringView>                  // for QStringView
-#include <QTextCodec>                   // for QTextCodec
-#include <QXmlStreamAttributes>         // for QXmlStreamAttributes
-#include <QXmlStreamReader>             // for QXmlStreamReader, QXmlStreamReader::Characters, QXmlStreamReader::EndElement, QXmlStreamReader::IncludeChildElements, QXmlStreamReader::StartDocument, QXmlStreamReader::StartElement
-#include <QtGlobal>                     // for qPrintable
-
-#include "defs.h"
 #include "xmlgeneric.h"
-#include "src/core/file.h"              // for File
 
+#include <utility>               // for as_const
 
-enum xg_shortcut {
-  xg_shortcut_none = 0,
-  xg_shortcut_skip,
-  xg_shortcut_ignore
-};
+#include <QByteArray>            // for QByteArray
+#include <QHash>                 // for QHash
+#include <QIODevice>             // for QIODevice
+#include <QLatin1Char>           // for QLatin1Char
+#include <QStringView>           // for QStringView
+#include <QTextCodec>            // for QTextCodec
+#include <QXmlStreamAttributes>  // for QXmlStreamAttributes, QXmlStreamReader::Characters, QXmlStreamReader::EndElement, QXmlStreamReader::IncludeChildElements, QXmlStreamReader::StartDocument, QXmlStreamReader::StartElement
+#include <QXmlStreamReader>      // for QXmlStreamReader
+//#include <QtCore>                // for QHash, QIODeviceBase::ReadOnly
+#include <QtGlobal>              // for qPrintable
 
-static const QList<xg_tag_map_entry>* xg_tag_tbl;
-static bool dynamic_tag_tbl;
-static QHash<QString, xg_shortcut>* xg_shortcut_taglist;
+#include "defs.h"                // for fatal
+#include "src/core/file.h"       // for File
 
-static QString rd_fname;
-static QByteArray reader_data;
-static const char* xg_encoding;
-static QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
-static QTextCodec* codec = utf8_codec;  // Qt has no vanilla ASCII encoding =(
 
 #define MYNAME "XML Reader"
 
@@ -63,107 +50,60 @@ static QTextCodec* codec = utf8_codec;  // Qt has no vanilla ASCII encoding =(
  * xml strains and insulates us from a lot of the grubbiness of expat.
  */
 
-static XgCallbackBase*
-xml_tbl_lookup(const QString& tag, xg_cb_type cb_type)
+XmlGenericReader::XgCallbackBase*
+XmlGenericReader::xml_tbl_lookup(const QString& tag, xg_cb_type cb_type)
 {
-  for (const auto& tm : *xg_tag_tbl) {
+  for (const auto& tm : std::as_const(xg_tag_tbl)) {
     if (cb_type == tm.cb_type) {
       QRegularExpressionMatch match = tm.tag_re.match(tag);
       if (match.hasMatch()) {
-        return tm.tag_cb;
+        return tm.tag_cb.get();
       }
     }
   }
   return nullptr;
 }
 
-static void
-xml_common_init(const QString& fname, const char* encoding,
-                const char* const* ignorelist, const char* const* skiplist)
+void
+XmlGenericReader::xml_common_init(const QString& fname, const char* encoding,
+         const char* const* ignorelist, const char* const* skiplist)
 {
   rd_fname = fname;
 
-  xg_encoding = encoding;
-  if (encoding) {
-    QTextCodec* tcodec = QTextCodec::codecForName(encoding);
-    if (tcodec) {
-      codec = tcodec;
+  if (encoding != nullptr) {
+    codec = QTextCodec::codecForName(encoding);
+    if (codec == nullptr) {
+      fatal(MYNAME " : codec \"%s\" is not available.\n", encoding);
     }
+  } else {
+    codec = QTextCodec::codecForName("UTF-8");
   }
 
-  xg_shortcut_taglist = new QHash<QString, xg_shortcut>;
+  xg_shortcut_taglist.clear();
   if (ignorelist != nullptr) {
     for (; ignorelist && *ignorelist; ++ignorelist) {
-      xg_shortcut_taglist->insert(QString::fromUtf8(*ignorelist), xg_shortcut_ignore);
+      xg_shortcut_taglist.insert(QString::fromUtf8(*ignorelist), xg_shortcut::sc_ignore);
     }
   }
   if (skiplist != nullptr) {
     for (; skiplist && *skiplist; ++skiplist) {
-      xg_shortcut_taglist->insert(QString::fromUtf8(*skiplist), xg_shortcut_skip);
-    }
-  }
-}
-
-void
-xml_init(const QString& fname, const QList<xg_tag_map_entry>* tbl, const char* encoding,
-         const char* const* ignorelist, const char* const* skiplist, bool dynamic_tbl)
-{
-  xg_tag_tbl = tbl;
-  dynamic_tag_tbl = dynamic_tbl;
-
-  xml_common_init(fname, encoding, ignorelist, skiplist);
-}
-
-void
-xml_init(const QString& fname, const QList<xg_tag_mapping>& tbl, const char* encoding,
-         const char* const* ignorelist, const char* const* skiplist)
-{
-  auto* tag_tbl = new QList<xg_tag_map_entry>;
-  dynamic_tag_tbl = true;
-  for (const auto& tm : tbl) {
-    auto* cb = new XgFunctionPtrCallback(tm.tag_cb);
-    QRegularExpression re(QRegularExpression::anchoredPattern(tm.tag_pattern));
-    assert(re.isValid());
-    tag_tbl->append({cb, tm.cb_type, re});
-  }
-  xg_tag_tbl = tag_tbl;
-
-  xml_common_init(fname, encoding, ignorelist, skiplist);
-}
-
-void
-xml_deinit()
-{
-  if (dynamic_tag_tbl) {
-    for (const auto& tm : *xg_tag_tbl) {
-      delete tm.tag_cb;
+      xg_shortcut_taglist.insert(QString::fromUtf8(*skiplist), xg_shortcut::sc_skip);
     }
-    delete xg_tag_tbl;
   }
-  xg_tag_tbl = nullptr;
-
-  reader_data.clear();
-  rd_fname.clear();
-
-  xg_encoding = nullptr;
-  codec = utf8_codec;
-
-  delete xg_shortcut_taglist;
-  xg_shortcut_taglist = nullptr;
 }
 
-static xg_shortcut
-xml_shortcut(QStringView name)
+XmlGenericReader::xg_shortcut
+XmlGenericReader::xml_shortcut(QStringView name)
 {
   QString key = name.toString();
-  if (xg_shortcut_taglist->contains(key)) {
-    return xg_shortcut_taglist->value(key);
+  if (xg_shortcut_taglist.contains(key)) {
+    return xg_shortcut_taglist.value(key);
   }
-  return xg_shortcut_none;
+  return xg_shortcut::sc_none;
 }
 
-static void
-xml_run_parser(QXmlStreamReader& reader)
+void
+XmlGenericReader::xml_run_parser(QXmlStreamReader& reader)
 {
   XgCallbackBase* cb;
   QString current_tag;
@@ -184,10 +124,10 @@ xml_run_parser(QXmlStreamReader& reader)
 
     case QXmlStreamReader::StartElement:
       switch (xml_shortcut(reader.name())) {
-      case xg_shortcut_skip:
+      case xg_shortcut::sc_skip:
         reader.skipCurrentElement();
         goto readnext;
-      case xg_shortcut_ignore:
+      case xg_shortcut::sc_ignore:
         goto readnext;
       default:
         break;
@@ -196,13 +136,13 @@ xml_run_parser(QXmlStreamReader& reader)
       current_tag.append(QLatin1Char('/'));
       current_tag.append(reader.qualifiedName());
 
-      cb = xml_tbl_lookup(current_tag, cb_start);
+      cb = xml_tbl_lookup(current_tag, xg_cb_type::cb_start);
       if (cb) {
         const QXmlStreamAttributes attrs = reader.attributes();
         (*cb)(nullptr, &attrs);
       }
 
-      cb = xml_tbl_lookup(current_tag, cb_cdata);
+      cb = xml_tbl_lookup(current_tag, xg_cb_type::cb_cdata);
       if (cb) {
         QString c = reader.readElementText(QXmlStreamReader::IncludeChildElements);
         // readElementText advances the tokenType to QXmlStreamReader::EndElement,
@@ -215,11 +155,11 @@ xml_run_parser(QXmlStreamReader& reader)
       break;
 
     case QXmlStreamReader::EndElement:
-      if (xml_shortcut(reader.name()) == xg_shortcut_skip) {
+      if (xml_shortcut(reader.name()) == xg_shortcut::sc_skip) {
         goto readnext;
       }
 
-      cb = xml_tbl_lookup(current_tag, cb_end);
+      cb = xml_tbl_lookup(current_tag, xg_cb_type::cb_end);
       if (cb) {
         (*cb)(reader.name().toString(), nullptr);
       }
@@ -242,7 +182,7 @@ readnext:
   }
 }
 
-void xml_read()
+void XmlGenericReader::xml_read()
 {
   gpsbabel::File file(rd_fname);
 
@@ -252,7 +192,7 @@ void xml_read()
 
   xml_run_parser(reader);
   if (reader.hasError())  {
-    fatal(MYNAME ":Read error: %s (%s, line %lld, col %lld)\n",
+    fatal(MYNAME " :Read error: %s (%s, line %lld, col %lld)\n",
           qPrintable(reader.errorString()),
           qPrintable(file.fileName()),
           reader.lineNumber(),
@@ -262,14 +202,14 @@ void xml_read()
 
 // Chucks some bytes into the global QByteArray buffer and waits for
 // xml_readstring() to parse.
-void xml_readprefixstring(const char* str)
+void XmlGenericReader::xml_readprefixstring(const char* str)
 {
   reader_data.append(str);
 }
 
 // Parses a bytestream as if it were a file. Looks for an <?xml encoding= to
 // determine file encoding, falls back to UTF-8 if unspecified.
-void xml_readstring(const char* str)
+void XmlGenericReader::xml_readstring(const char* str)
 {
   reader_data.append(str);
 
@@ -277,7 +217,7 @@ void xml_readstring(const char* str)
 
   xml_run_parser(reader);
   if (reader.hasError())  {
-    fatal(MYNAME ":Read error: %s (%s, line %lld, col %lld)\n",
+    fatal(MYNAME " :Read error: %s (%s, line %lld, col %lld)\n",
           qPrintable(reader.errorString()),
           "unknown",
           reader.lineNumber(),
@@ -287,7 +227,7 @@ void xml_readstring(const char* str)
 
 // This is quite different from xml_readstring(). It doesn't have to interpret
 // encoding because the source is already Qt's internal UTF-16.
-void xml_readunicode(const QString& str)
+void XmlGenericReader::xml_readunicode(const QString& str)
 {
   QXmlStreamReader reader(str);
 
index 101efa3d3945b076fc44711c27ee150ffb788921..aec623b84206672a28f3322bc3a52dd66f8cadb7 100644 (file)
 #define XMLGENERIC_H_INCLUDED_
 
 #include <cassert>               // for assert
+#include <memory>                // for make_shared, shared_ptr
 
+#include <QByteArray>            // for QByteArray
+#include <QHash>                 // for QHash
 #include <QList>                 // for QList
 #include <QRegularExpression>    // for QRegularExpression
 #include <QString>               // for QString
+#include <QStringView>           // for QStringView
+#include <QTextCodec>            // for QTextCodec
 #include <QXmlStreamAttributes>  // for QXmlStreamAttributes
+#include <QXmlStreamReader>      // for QXmlStreamReader
 
 
-// Maybe the XmlGeneric string callback really shouldn't have a type
-// of its own; this was a crutch during the move from char* to QString.
-// It's "just" a search and replace to make it go away, but it might
-// be convenient to overload some day.
-using xg_string = const QString&;
-
-enum xg_cb_type {
-  cb_start = 1,
+enum class xg_cb_type {
+  cb_unknown = 0,
+  cb_start,
   cb_cdata,
   cb_end,
 };
 
-class XgCallbackBase
-{
-public:
-  XgCallbackBase() = default;
-  virtual ~XgCallbackBase() = default;
-  XgCallbackBase(const XgCallbackBase&) = delete;
-  XgCallbackBase& operator=(const XgCallbackBase&) = delete;
-  XgCallbackBase(XgCallbackBase&&) = delete;
-  XgCallbackBase& operator=(XgCallbackBase&&) = delete;
-
-  virtual void operator()(xg_string string, const QXmlStreamAttributes* attrs) const = 0;
-};
-
-template<class XgFormat>
-class XgFunctor : public XgCallbackBase
+/*
+ *  xml_init will build and own a table of XgFunctor and/or
+ *  XgFunctionPtrCallback entries from a list
+ *  of non-static member functions and/or function pointers.
+ *
+ *  QList<XmlGenericReader::xg_fmt_map_entry<SomeFormat>> some_map = {
+ *    {&SomeFormat::memberfn, cb_start, "/Placemark"},
+ *    {staticfn, cb_cdata, "/Placemark/coord"},
+ *  };
+ *
+ *  The this pointer from the Format instance must be passed if any
+ *  of the callbacks are member functions, otherwise nullptr can be passed
+ *  as this.
+ *
+ *  xml_init(fname, this, some_map, encoding, ignorelist, skiplist);
+ *
+ */
+class XmlGenericReader
 {
 public:
-  using XgCb = void (XgFormat::*)(xg_string, const QXmlStreamAttributes*);
-  XgFunctor(XgFormat* obj, XgCb cb) : that_(obj), cb_(cb) {}
-  void operator()(xg_string string, const QXmlStreamAttributes* attrs) const override
+  /* Types */
+
+  // formats pass a list containing member function pointers and/or function pointers.
+  template<class MyFormat>
+  struct xg_fmt_map_entry {
+    // Constructor from a Member Function Pointer
+    using XgMfpCb = void (MyFormat::*)(const QString&, const QXmlStreamAttributes*);
+    xg_fmt_map_entry(XgMfpCb mfp, xg_cb_type ty, const char* tp) : tag_mfp_cb(mfp), cb_type(ty), tag_pattern(tp) {}
+    // Constructor from a Function Pointer.
+    using XgFpCb = void (const QString&, const QXmlStreamAttributes*);
+    xg_fmt_map_entry(XgFpCb fp, xg_cb_type ty, const char* tp) : tag_fp_cb(fp), cb_type(ty), tag_pattern(tp) {}
+
+    /* Data Members */
+
+    XgMfpCb tag_mfp_cb{nullptr};
+    XgFpCb* tag_fp_cb{nullptr};
+    xg_cb_type cb_type{xg_cb_type::cb_unknown};
+    const char* tag_pattern{nullptr};
+  };
+
+  /* Member Functions */
+
+  template<class MyFormat>
+  void xml_init(const QString& fname, MyFormat* instance, const QList<xg_fmt_map_entry<MyFormat>>& tbl,
+                const char* encoding = nullptr,
+                const char* const* ignorelist = nullptr,
+                const char* const* skiplist = nullptr)
   {
-    (that_->*cb_)(string, attrs);
+    build_xg_tag_map(instance, tbl);
+
+    xml_common_init(fname, encoding, ignorelist, skiplist);
   }
 
+  void xml_read();
+  void xml_readstring(const char* str);
+  void xml_readprefixstring(const char* str);
+  void xml_readunicode(const QString& str);
+
 private:
-  XgFormat* that_;
-  XgCb cb_;
-};
+  /* Types */
 
-class XgFunctionPtrCallback : public XgCallbackBase
-{
-public:
-  using XgCb = void (xg_string, const QXmlStreamAttributes*);
-  explicit XgFunctionPtrCallback(XgCb cb) : cb_(cb) {}
-  void operator()(xg_string string, const QXmlStreamAttributes* attrs) const override
+  class XgCallbackBase
+  {
+  public:
+    XgCallbackBase() = default;
+    virtual ~XgCallbackBase() = default;
+    XgCallbackBase(const XgCallbackBase&) = delete;
+    XgCallbackBase& operator=(const XgCallbackBase&) = delete;
+    XgCallbackBase(XgCallbackBase&&) = delete;
+    XgCallbackBase& operator=(XgCallbackBase&&) = delete;
+
+    virtual void operator()(const QString& string, const QXmlStreamAttributes* attrs) const = 0;
+  };
+
+  template<class XgFormat>
+  class XgFunctor : public XgCallbackBase
   {
-    (*cb_)(string, attrs);
+  public:
+    using XgCb = void (XgFormat::*)(const QString&, const QXmlStreamAttributes*);
+    XgFunctor(XgFormat* obj, XgCb cb) : that_(obj), cb_(cb) {}
+    void operator()(const QString& string, const QXmlStreamAttributes* attrs) const override
+    {
+      (that_->*cb_)(string, attrs);
+    }
+
+  private:
+    XgFormat* that_;
+    XgCb cb_;
+  };
+
+  class XgFunctionPtrCallback : public XgCallbackBase
+  {
+  public:
+    using XgCb = void (const QString&, const QXmlStreamAttributes*);
+    explicit XgFunctionPtrCallback(XgCb cb) : cb_(cb) {}
+    void operator()(const QString& string, const QXmlStreamAttributes* attrs) const override
+    {
+      (*cb_)(string, attrs);
+    }
+
+  private:
+    XgCb* cb_;
+  };
+
+  // xml processing uses a list of xg_tag_map_entries.
+  struct xg_tag_map_entry {
+    std::shared_ptr<XgCallbackBase> tag_cb{nullptr};
+    xg_cb_type cb_type{xg_cb_type::cb_unknown};
+    QRegularExpression tag_re;
+  };
+
+  enum class xg_shortcut {
+    sc_none = 0,
+    sc_skip,
+    sc_ignore
+  };
+
+  /* Member Functions */
+
+  XgCallbackBase* xml_tbl_lookup(const QString& tag, xg_cb_type cb_type);
+  void xml_common_init(const QString& fname, const char* encoding,
+                       const char* const* ignorelist, const char* const* skiplist);
+  xg_shortcut xml_shortcut(QStringView name);
+  void xml_run_parser(QXmlStreamReader& reader);
+
+  // translate xg_fmt_map_entries to xg_tag_map_entries.
+  template<class MyFormat>
+  void build_xg_tag_map(MyFormat* instance, const QList<xg_fmt_map_entry<MyFormat>>& map)
+  {
+    xg_tag_tbl.clear();
+    for (const auto& entry : map) {
+      xg_tag_map_entry tme;
+      if (entry.tag_mfp_cb != nullptr) {
+        tme.tag_cb = std::make_shared<XgFunctor<MyFormat>>(instance, entry.tag_mfp_cb);
+      } else {
+        tme.tag_cb = std::make_shared<XgFunctionPtrCallback>(entry.tag_fp_cb);
+      }
+      QRegularExpression re(QRegularExpression::anchoredPattern(entry.tag_pattern));
+      assert(re.isValid());
+      tme.cb_type = entry.cb_type;
+      tme.tag_re = re;
+      xg_tag_tbl.append(tme);
+    }
   }
 
-private:
-  XgCb* cb_;
-};
+  /* Data Members */
 
-// xml processing uses a QList<xg_tag_map_entry>.
-// You may generated this yourself.  See method 1 below.
-// Or it may be generated for you using one of the subsequent
-// methods.
-struct xg_tag_map_entry {
-  XgCallbackBase* tag_cb;
-  xg_cb_type cb_type;
-  QRegularExpression tag_re;
-};
+  QList<xg_tag_map_entry> xg_tag_tbl;
+  QHash<QString, xg_shortcut> xg_shortcut_taglist;
 
-// Table generation from an array containing function pointers.
-// The above table can be generated by xml_init.  See method 2 below.
-// This is how things done historically before the Format class was
-// introduced.
-using xg_callback = void (xg_string, const QXmlStreamAttributes*);
-struct xg_tag_mapping {
-  xg_callback* tag_cb;
-  xg_cb_type cb_type;
-  const char* tag_pattern;
-};
+  QString rd_fname;
+  QByteArray reader_data;
+  QTextCodec* codec{nullptr};  // Qt has no vanilla ASCII encoding =(
 
-// Table generation from a list containing member function pointers.
-// The above table can be generated by xml_init.  See method 3 below.
-template<class MyFormat>
-struct xg_functor_map_entry {
-  using XgCb = void (MyFormat::*)(xg_string, const QXmlStreamAttributes*);
-  XgCb tag_cb;
-  xg_cb_type cb_type;
-  const char* tag_pattern;
 };
 
-template<class MyFormat, typename my_functor_map_entry>
-QList<xg_tag_map_entry>* build_xg_tag_map(MyFormat* instance, const QList<my_functor_map_entry>& map)
-{
-  auto* tag_tbl = new QList<xg_tag_map_entry>;
-  for (const auto& entry : map) {
-    auto* tag_cb = new XgFunctor<MyFormat>(instance, entry.tag_cb);
-    QRegularExpression re(QRegularExpression::anchoredPattern(entry.tag_pattern));
-    assert(re.isValid());
-    tag_tbl->append({tag_cb, entry.cb_type, re});
-  }
-  return tag_tbl;
-}
-
-/*
- * There are multiple ways to initialize with xml_init.
- *
- * 1. Build your own QList<xg_tag_map_entry>, and pass it.
- *    You own the table, you must do any required clean up.
- *    Your callbacks may be a mix of function pointers wrapped in XgFunctors
- *    and non-static member functions wrapped in XgFunctionPtrCallbacks.
- *    and XgFunctionPtrCallback(for static member functions or global functions) entries.
- *    xml_init(fname, tbl, encoding, ignorelist, skiplist, false);
- *    You must set the dynamic_tbl parameter to false so xml_deninit doesn't
- *    attempt to free the table resources when xml_deinit is called.
- *
- * 2. Have xml_init build and own a table of XgFunctionPtrCallback entries
- *    from an list of function pointers, i.e. a QList of xg_tag_mapping elements.
- *    This only works when all callbacks are function pointers.
- *    xml_init(fname, tbl, encoding, ignorelist, skiplist);
- *    Generated table entries will automatically be freed.
- *
- * 3. Have xml_init build and own a table of XgFunctor entries from a list
- *    of non-static member functions, i.e. a QList<my_functor_map_entry>.
- *    This only works when all callbacks are non-static member functions.
- *    xml_init(fname, build_xg_tag_map(instance, map), encoding, ignorelist, skiplist, true);
- *    You must set the dynamic_tbl parameter to true to free the generated table
- *    resources when xml_deinit is called.
- *
- */
-void xml_init(const QString& fname, const QList<xg_tag_map_entry>* tbl, const char* encoding,
-              const char* const* ignorelist = nullptr,
-              const char* const* skiplist = nullptr, bool dynamic_tbl = false);
-void xml_init(const QString& fname, const QList<xg_tag_mapping>& tbl,const char* encoding,
-              const char* const* ignorelist = nullptr,
-              const char* const* skiplist = nullptr);
-void xml_read();
-void xml_readstring(const char* str);
-void xml_readprefixstring(const char* str);
-void xml_readunicode(const QString& str);
-void xml_deinit();
-
 #endif  // XMLGENERIC_H_INCLUDED_